﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security;
using System.Text.RegularExpressions;
using System.Windows;
using System.Xml;
using System.Xml.Linq;
using XML_VML.Object;
using Point = System.Windows.Point;

namespace XML_VML
{
    public static class FileManager
    {
        public static bool Cancel = false;
        public static string NAMESPACE = "urn:schemas-microsoft-com:vml";
        private static readonly XmlReaderSettings Settings = new XmlReaderSettings();

        public static List<VObject> ReadFile(string fileName)
        {
            string allString;
            try
            {
                var doc = XDocument.Load(fileName);
                allString = doc.ToString();
            }
            catch (Exception e)
            {
                MessageBox.Show("Có lỗi trong quá trình parse xml: " + e.Message);
                return null;
            }

            var listObjects = new List<VObject>();
            Settings.ConformanceLevel = ConformanceLevel.Fragment;
            try
            {
                using (var xmlReader = XmlReader.Create(new StringReader(allString), Settings))
                {
                    while (xmlReader.Read() && !Cancel)
                    {
                        if (xmlReader.NodeType == XmlNodeType.Element)
                        {
                            switch (xmlReader.Name)
                            {
                                case "v:shape":
                                    var tempShape = ReadShape(xmlReader);
                                    if(true)
                                    {
                                        listObjects.Add(tempShape);
                                    }
                                    break;
                                case "v:shapetype":
                                    var tempShapeType = ReadShapeType(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempShapeType);
                                    }
                                    break;
                                case "v:group":
                                    var tempGroup = ReadGroup(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempGroup);
                                    }
                                    break;
                                case "v:line":
                                    var tempLine = ReadLine(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempLine);
                                    }
                                    break;
                                case "v:polyline":
                                    var tempPLine = ReadPolyLine(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempPLine);
                                    }
                                    break;
                                case "v:curve":
                                    var tempCurve = ReadCurve(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempCurve);
                                    }
                                    break;
                                case "v:rect":
                                    var tempRect = ReadRect(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempRect);
                                    }
                                    break;
                                case "v:roundrect":
                                    var tempRoundRect = ReadRoundRect(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempRoundRect);
                                    }
                                    break;
                                case "v:oval":
                                    var tempOval = ReadOval(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempOval);
                                    }
                                    break;
                                case "v:arc":
                                    var tempArc = ReadArc(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempArc);
                                    }
                                    break;
                                case "v:image":
                                    var tempImage = ReadImage(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempImage);
                                    }
                                    break;
                                case "v:background":
                                    var tempBg = ReadBackground(xmlReader);
                                    if (true)
                                    {
                                        listObjects.Add(tempBg);
                                    }
                                    break;
                            }
                        }
                    }
                }
            }
            catch (ArgumentNullException)
            {
                MessageBox.Show("Tham số truyền vào là null!", "Lỗi", MessageBoxButton.OK);
            }
            catch (SecurityException)
            {
                MessageBox.Show("Lỗi bảo mật!", "Lỗi", MessageBoxButton.OK);
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("Tập tin vừa nhập không được tìm thấy!", "Lỗi", MessageBoxButton.OK);
            }
            catch (Exception e)
            {
                MessageBox.Show("Có lỗi khi đọc tệp" + e.Message, "Lỗi", MessageBoxButton.OK);
            }

            return listObjects;
        }

        private static VShape       ReadShape(XmlReader reader)
        {
            var rs = new VShape();

            ReadBasedAtt(reader,ref rs);

            try
            {
                //checked
                string temp;
                if ((temp = reader.GetAttribute("type")) != null)
                {
                    rs.Type = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("adj")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    rs.Adj = GetStringFromIntArray(number);
                }

                //checked
                if ((temp = reader.GetAttribute("path")) != null)
                {
                    var obs = GetVFromString(RemoveMulipleSpaces(temp));
                    rs.Path = GetStringFromV(obs);
                }

                //checked
                if ((temp = reader.GetAttribute("v")) != null)
                {
                    rs.V = RemoveMulipleSpaces(temp);
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }

            //Read Shape Elements
            var inner = reader.ReadInnerXml();
            using (var shapeReader = XmlReader.Create(new StringReader(inner), Settings))
            {
                while (shapeReader.Read() && !Cancel)
                {
                    if (shapeReader.NodeType == XmlNodeType.Element)
                    {
                        switch (shapeReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(shapeReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(shapeReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(shapeReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(shapeReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(shapeReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(shapeReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(shapeReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(shapeReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(shapeReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VShapeType   ReadShapeType(XmlReader reader)
        {
            var rs = new VShapeType();

            ReadBasedAtt(reader, ref rs);

            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("adj")) != null)
                {
                    var number = GetIntFromStringListSepByComma(RemoveMulipleSpaces(temp));
                    rs.Adj = GetStringFromIntArray(number);
                }

                //checked
                if ((temp = reader.GetAttribute("path")) != null)
                {
                    var obs = GetVFromString(RemoveMulipleSpaces(temp));
                    rs.Path = GetStringFromV(obs);
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }

            //Read ShapeType Elements
            var inner = reader.ReadInnerXml().Trim();
            
            using (var shapeReader = XmlReader.Create(new StringReader(inner), Settings))
            {
                while (shapeReader.Read() && !Cancel)
                {
                    if (shapeReader.NodeType == XmlNodeType.Element)
                    {
                        switch (shapeReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(shapeReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(shapeReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(shapeReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(shapeReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(shapeReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(shapeReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(shapeReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(shapeReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(shapeReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VLine        ReadLine(XmlReader reader)
        {
            var rs = new VLine();
            ReadBasedAtt(reader,ref rs);

            try
            {
                //checked
                string temp;
                if ((temp = reader.GetAttribute("from")) != null)
                {
                    rs.From = GetPointFromString(temp, 0, 0);

                }

                //checked
                if ((temp = reader.GetAttribute("to")) != null)
                {
                    rs.To = GetPointFromString(temp, 10, 10);
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }

            //Read Line Elements
            var inner = reader.ReadInnerXml();
            using (var lineReader = XmlReader.Create(new StringReader(inner), Settings))
            {
                while (lineReader.Read() && !Cancel)
                {
                    if (lineReader.NodeType == XmlNodeType.Element)
                    {
                        switch (lineReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(lineReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(lineReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(lineReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(lineReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(lineReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(lineReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(lineReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(lineReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(lineReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VPolyLine    ReadPolyLine(XmlReader reader)
        {
            var rs = new VPolyLine();
            ReadBasedAtt(reader, ref rs);

            try
            {
                string temp;
                if ((temp = reader.GetAttribute("points")) != null)
                {
                    var strNum = Regex.Split(temp, @"\d+");
                    for(var i = 0; i< strNum.Length/2; i++)
                    {
                        int first, second;

                        if (!int.TryParse(strNum[i*2].Trim(), out first) || !int.TryParse(strNum[i*2 + 1].Trim(), out second))
                            continue;
                        var zz = new Point(first, second);
                        rs.Points.Add(zz);
                    }
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }

            //Read PolyLine Elements
            var inner = reader.ReadInnerXml();
            using (var lineReader = XmlReader.Create(new StringReader(inner), Settings))
            {
                while (lineReader.Read() && !Cancel)
                {
                    if (lineReader.NodeType == XmlNodeType.Element)
                    {
                        switch (lineReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(lineReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(lineReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(lineReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(lineReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(lineReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(lineReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(lineReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(lineReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(lineReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VCurve       ReadCurve(XmlReader reader)
        {
            var rs = new VCurve();
            ReadBasedAtt(reader, ref rs);

            try
            {
                string temp;
                if ((temp = reader.GetAttribute("from")) != null)
                {
                    rs.From = GetPointFromString(temp, 0, 0);
                }

                if ((temp = reader.GetAttribute("control1")) != null)
                {
                    rs.Control1 = GetPointFromString(temp, 10, 10);
                }

                if ((temp = reader.GetAttribute("control2")) != null)
                {
                    rs.Control2 = GetPointFromString(temp, 20, 0);
                }

                if ((temp = reader.GetAttribute("to")) != null)
                {
                    rs.To = GetPointFromString(temp, 30, 20);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }

            //Read Curve Elements
            var inner = reader.ReadInnerXml();
            using (var curveReader = XmlReader.Create(new StringReader(inner), Settings))
            {
                while (curveReader.Read() && !Cancel)
                {
                    if (curveReader.NodeType == XmlNodeType.Element)
                    {
                        switch (curveReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(curveReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(curveReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(curveReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(curveReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(curveReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(curveReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(curveReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(curveReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(curveReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VRect        ReadRect(XmlReader reader)
        {
            var rs = new VRect();
            ReadBasedAtt(reader, ref rs);
            
            //Read Rect Elements
            var inner = reader.ReadInnerXml();
            using (var curveReader = XmlReader.Create(new StringReader(inner), Settings))
            {
                while (curveReader.Read() && !Cancel)
                {
                    if (curveReader.NodeType == XmlNodeType.Element)
                    {
                        switch (curveReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(curveReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(curveReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(curveReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(curveReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(curveReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(curveReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(curveReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(curveReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(curveReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VRoundRect   ReadRoundRect(XmlReader reader)
        {
            var rs = new VRoundRect();
            ReadBasedAtt(reader, ref rs);

            try
            {
                string temp;
                if ((temp = reader.GetAttribute("arcsize")) != null)
                {
                    rs.ArcSize = GetFloatFromString(temp, 0.2f);
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }

            //Read Rect Elements
            var inner = reader.ReadInnerXml();
            using (var curveReader = XmlReader.Create(new StringReader(inner), Settings))
            {
                while (curveReader.Read() && !Cancel)
                {
                    if (curveReader.NodeType == XmlNodeType.Element)
                    {
                        switch (curveReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(curveReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(curveReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(curveReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(curveReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(curveReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(curveReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(curveReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(curveReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(curveReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VOval        ReadOval(XmlReader reader)
        {
            var rs = new VOval();
            ReadBasedAtt(reader, ref rs);

            //Read Oval Elements
            var inner = reader.ReadInnerXml();
            using (var curveReader = XmlReader.Create(new StringReader(inner), Settings))
            {
                while (curveReader.Read() && !Cancel)
                {
                    if (curveReader.NodeType == XmlNodeType.Element)
                    {
                        switch (curveReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(curveReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(curveReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(curveReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(curveReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(curveReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(curveReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(curveReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(curveReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(curveReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VArc         ReadArc(XmlReader reader)
        {
            var rs = new VArc();
            ReadBasedAtt(reader, ref rs);

            try
            {
                string temp;
                if ((temp = reader.GetAttribute("startangle")) != null)
                {
                    rs.StartAngle = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("endangle")) != null)
                {
                    rs.EndAngle = GetIntegerFromString(temp, 90);
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }

            //Read Arc Elements
            var inner = reader.ReadInnerXml();
            using (var curveReader = XmlReader.Create(new StringReader(inner),Settings))
            {
                while (curveReader.Read() && !Cancel)
                {
                    if (curveReader.NodeType == XmlNodeType.Element)
                    {
                        switch (curveReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(curveReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(curveReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(curveReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(curveReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(curveReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(curveReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(curveReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(curveReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(curveReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VImage       ReadImage(XmlReader reader)
        {
            var rs = new VImage();
            ReadBasedAtt(reader, ref rs);

            try
            {
                string temp;
                if ((temp = reader.GetAttribute("src")) != null)
                {
                    rs.Src = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("cropleft")) != null)
                {
                    rs.CropLeft = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("croptop")) != null)
                {
                    rs.CropTop = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("cropright")) != null)
                {
                    rs.CropRight = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("cropbottom")) != null)
                {
                    rs.CropBottom = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("gain")) != null)
                {
                    rs.Gain = GetIntegerFromString(temp, 1);
                }

                if ((temp = reader.GetAttribute("blacklevel")) != null)
                {
                    rs.BlackLevel = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("gamma")) != null)
                {
                    rs.Gamma = GetIntegerFromString(temp, 1);
                }

                if ((temp = reader.GetAttribute("embosscolor")) != null)
                {
                    rs.EmbossColor = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("grayscale")) != null)
                {
                    rs.GrayScale = GetTrueFalseStringValue(temp, false);
                }

                if ((temp = reader.GetAttribute("bilevel")) != null)
                {
                    rs.Bilevel = GetTrueFalseStringValue(temp, false);
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }

            //Read Image Elements
            var inner = reader.ReadInnerXml();
            using (var imageReader = XmlReader.Create(new StringReader(inner), Settings))
            {
                while (imageReader.Read() && !Cancel)
                {
                    if (imageReader.NodeType == XmlNodeType.Element)
                    {
                        switch (imageReader.Name)
                        {
                            case "v:path":
                                rs.Elements.Add(ReadPath(imageReader));
                                break;
                            case "v:formulas":
                                rs.Elements.Add(ReadFomulas(imageReader));
                                break;
                            case "v:handles":
                                rs.Elements.Add(ReadHandles(imageReader));
                                break;
                            case "v:fill":
                                rs.Elements.Add(ReadFill(imageReader));
                                break;
                            case "v:stroke":
                                rs.Elements.Add(ReadStroke(imageReader));
                                break;
                            case "v:shadow":
                                rs.Elements.Add(ReadShadow(imageReader));
                                break;
                            case "v:textbox":
                                rs.Elements.Add(ReadTextBox(imageReader));
                                break;
                            case "v:textpath":
                                rs.Elements.Add(ReadTextPath(imageReader));
                                break;
                            case "v:imagedata":
                                rs.Elements.Add(ReadImageData(imageReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static VGroup       ReadGroup(XmlReader reader)
        {
            var rs = new VGroup();
            ReadBasedAtt(reader, ref rs);

            var temp = reader.ReadInnerXml();

            using (var groupReader = XmlReader.Create(new StringReader(temp),Settings))
            {
                while (groupReader.Read() && !Cancel)
                {
                    if (groupReader.NodeType == XmlNodeType.Element)
                    {
                        switch (groupReader.Name)
                        {
                            case "v:group":
                                rs.Elements.Add(ReadGroup(groupReader));
                                break;
                            case "v:shape":
                                rs.Elements.Add(ReadShape(groupReader));
                                break;
                            case "v:shapetype":
                                rs.Elements.Add(ReadShapeType(groupReader));
                                break;
                            case "v:line":
                                rs.Elements.Add(ReadLine(groupReader));
                                break;
                            case "v:polyline":
                                rs.Elements.Add(ReadPolyLine(groupReader));
                                break;
                            case "v:curve":
                                rs.Elements.Add(ReadCurve(groupReader));
                                break;
                            case "v:rect":
                                rs.Elements.Add(ReadRect(groupReader));
                                break;
                            case "v:roundrect":
                                rs.Elements.Add(ReadRoundRect(groupReader));
                                break;
                            case "v:oval":
                                rs.Elements.Add(ReadOval(groupReader));
                                break;
                            case "v:arc":
                                rs.Elements.Add(ReadArc(groupReader));
                                break;
                            case "v:image":
                                rs.Elements.Add(ReadImage(groupReader));
                                break;
                        }
                    }
                }
            }
            return rs;
        }
        
        private static VBackground  ReadBackground(XmlReader reader)
        {
            var rs = new VBackground();
            ReadBasedAtt(reader, ref rs);

            var inner = reader.ReadInnerXml();
            using (var bgReader = XmlReader.Create(new StringReader(inner),Settings))
            {
                while (bgReader.Read() && !Cancel)
                {
                    if (bgReader.NodeType == XmlNodeType.Element)
                    {
                        switch (bgReader.Name)
                        {
                            case "v:fill":
                                rs.FillElement = ReadFill(bgReader);
                                break;
                        }
                    }
                }
            }
            return rs;
        }

        private static void ReadBasedAtt(XmlReader reader, ref VShape rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------
                
                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp,0.75f);         
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if(number.Length%2 != 0)
                    {
                        Array.Resize(ref number,number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {
                
            }
            catch(InvalidOperationException)
            {
                
            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VShapeType rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp, 0.75f);
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VLine rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp, 0.75f);
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VPolyLine rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp, 0.75f);
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VCurve rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp, 0.75f);
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VRect rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp, 0.75f);
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VRoundRect rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp, 0.75f);
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VOval rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp, 0.75f);
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VArc rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp, 0.75f);
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VImage rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                //checked
                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = CheckColorFromString(temp) ? temp.Trim().ToLower() : null;
                }

                //checked
                if ((temp = reader.GetAttribute("stroke")) != null)
                {
                    rs.Stroke = GetTrueFalseStringValue(temp.ToLower(), true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokecolor")) != null)
                {
                    rs.StrokeColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "black";
                }

                //checked
                if ((temp = reader.GetAttribute("strokeweight")) != null)
                {
                    rs.StrokeWeight = GetFloatFromString(temp, 0.75f);
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }

                //checked
                if ((temp = reader.GetAttribute("print")) != null)
                {
                    rs.Print = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VGroup rs)
        {
            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("href")) != null)
                {
                    rs.Href = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("target")) != null)
                {
                    rs.Target = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("class")) != null)
                {
                    rs.Class = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("title")) != null)
                {
                    rs.Title = RemoveMulipleSpaces(temp);
                }

                //checked
                if ((temp = reader.GetAttribute("alt")) != null)
                {
                    rs.Alt = RemoveMulipleSpaces(temp);
                }

                //CSS Attributes -----------------------------------------
                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
                //END CSS ------------------------------------------------

                //checked
                if ((temp = reader.GetAttribute("coordsize")) != null)
                {
                    rs.CoordSize = GetPointFromString(temp, 1000, 1000);
                }

                //checked
                if ((temp = reader.GetAttribute("coordorigin")) != null)
                {
                    rs.CoordOrigin = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("wrapcoords")) != null)
                {
                    var number = GetIntFromStringListSepByComma(temp.Trim());
                    if (number.Length % 2 != 0)
                    {
                        Array.Resize(ref number, number.Length - 1);
                    }
                    rs.WrapCoords = GetStringFromIntArray(number);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        private static void ReadBasedAtt(XmlReader reader, ref VBackground rs)
        {
            try
            {
                //checked
                string temp;
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("fill")) != null)
                {
                    rs.Fill = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("fillcolor")) != null)
                {
                    rs.FillColor = CheckColorFromString(temp) ? temp.Trim().ToLower() : "white";
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
        }

        #region READPATH
        private static VPath ReadPath(XmlReader reader)
        {
            var rs = new VPath();

            try
            {
                string temp;

                //checked
                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                //checked
                if ((temp = reader.GetAttribute("v")) != null)
                {
                    var obs = GetVFromString(RemoveMulipleSpaces(temp));
                    rs.V = GetStringFromV(obs);
                }

                //checked
                if ((temp = reader.GetAttribute("limo")) != null)
                {
                    rs.Limo = GetPointFromString(temp, 0, 0);
                }

                //checked
                if ((temp = reader.GetAttribute("fillok")) != null)
                {
                    rs.FillOk = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("strokeok")) != null)
                {
                    rs.StrokeOk = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("shadowok")) != null)
                {
                    rs.ShadowOk = GetTrueFalseStringValue(temp, true);
                }

                //checked
                if ((temp = reader.GetAttribute("arrowok")) != null)
                {
                    rs.ArrowOk = GetTrueFalseStringValue(temp, false);
                }

                //checked
                if ((temp = reader.GetAttribute("gradientshapeok")) != null)
                {
                    rs.GradientShapeOK = GetTrueFalseStringValue(temp, false);
                }

                //checked
                if ((temp = reader.GetAttribute("textpathok")) != null)
                {
                    rs.TextPathOK = GetTrueFalseStringValue(temp, false);
                }

                //checked
                if ((temp = reader.GetAttribute("textboxrect")) != null)
                {
                    rs.TextBoxRect = RemoveMulipleSpaces(temp);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
            return rs;
        }
        #endregion

        #region READFOMULAS
        private static VFormulas ReadFomulas(XmlReader reader)
        {
            var rs = new VFormulas();

            using (var fReader = reader.ReadSubtree())
            {
                while (fReader.Read() && !Cancel)
                {
                    if (fReader.NodeType == XmlNodeType.Element)
                    {
                        switch (fReader.Name)
                        {
                            case "v:f":
                                string temp;
                                if ((temp = reader.GetAttribute("eqn")) != null)
                                {
                                    var f = new VF {eqn = temp};
                                    rs.Elements.Add(f);
                                }
                                break;
                            
                        }
                    }
                }
            }
            return rs;
        }
        #endregion

        #region READHANDLES
        private static VHandles ReadHandles(XmlReader reader)
        {
            var rs = new VHandles();

            using (var hReader = reader.ReadSubtree())
            {
                while (hReader.Read() && !Cancel)
                {
                    if (hReader.NodeType == XmlNodeType.Element)
                    {
                        switch (hReader.Name)
                        {
                            case "v:h":
                                var vh = new VH();
                                string temp;

                                //checked
                                if ((temp = reader.GetAttribute("position")) != null)
                                {
                                    vh.Position = GetPointFromString(temp, 0, 0);
                                }

                                //checked
                                if ((temp = reader.GetAttribute("polar")) != null)
                                {
                                    vh.Polar = GetPointFromString(temp, int.MinValue, int.MinValue);
                                }

                                //checked
                                if ((temp = reader.GetAttribute("map")) != null)
                                {
                                    vh.Map = GetPointFromString(temp, 0, 1000);
                                }

                                //checked
                                if ((temp = reader.GetAttribute("invx")) != null)
                                {
                                    vh.InvX = GetTrueFalseStringValue(temp, false);
                                }

                                //checked
                                if ((temp = reader.GetAttribute("invy")) != null)
                                {
                                    vh.InvY = GetTrueFalseStringValue(temp, false);
                                }

                                //checked
                                if ((temp = reader.GetAttribute("switch")) != null)
                                {
                                    vh.Switch = GetTrueFalseStringValue(temp, false);
                                }

                                //checked
                                if ((temp = reader.GetAttribute("xrange")) != null)
                                {
                                    vh.XRange = GetPointFromString(temp, 0, 0);
                                }

                                //checked
                                if ((temp = reader.GetAttribute("yrange")) != null)
                                {
                                    vh.YRange = GetPointFromString(temp, 0, 0);
                                }

                                //checked
                                if ((temp = reader.GetAttribute("radiusrange")) != null)
                                {
                                    vh.RadiusRange = GetPointFromString(temp, 0, 0);
                                }

                                rs.Elements.Add(vh);
                                break;

                        }
                    }
                }
            }
            return rs;
        }
        #endregion

        #region READFILL
        private static VFill ReadFill(XmlReader reader)
        {
            var rs = new VFill();

            try
            {
                string temp;

                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                if ((temp = reader.GetAttribute("type")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "solid":
                            rs.Type = temp;
                            break;
                        case "gradient":
                            rs.Type = temp;
                            break;
                        case "gradientradial":
                            rs.Type = temp;
                            break;
                        case "tile":
                            rs.Type = temp;
                            break;
                        case "pattern":
                            rs.Type = temp;
                            break;
                        case "frame":
                            rs.Type = temp;
                            break;
                        default:
                            rs.Type = "solid";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("on")) != null)
                {
                    rs.On = GetTrueFalseStringValue(temp, true);
                }

                if ((temp = reader.GetAttribute("color")) != null)
                {
                    rs.Color = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                if ((temp = reader.GetAttribute("color2")) != null)
                {
                    rs.Color2 = rs.Color = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("src")) != null)
                {
                    rs.Src = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("size")) != null)
                {
                    rs.Size = GetPointFromString(temp, int.MinValue, int.MinValue);
                }

                if ((temp = reader.GetAttribute("origin")) != null)
                {
                    rs.Origin = GetPointFromString(temp, int.MinValue, int.MinValue);
                }

                if ((temp = reader.GetAttribute("position")) != null)
                {
                    rs.Position = GetPointFromString(temp, int.MinValue, int.MinValue);
                }

                if ((temp = reader.GetAttribute("aspect")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "ignore":
                            rs.Aspect = temp;
                            break;
                        case "atleast":
                            rs.Aspect = temp;
                            break;
                        case "atmost":
                            rs.Aspect = temp;
                            break;
                        default:
                            rs.Aspect = "ignore";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("alignshape")) != null)
                {
                    rs.AlignShape = GetTrueFalseStringValue(temp, true);
                }

                if ((temp = reader.GetAttribute("colors")) != null)
                {
                    rs.Colors = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("angle")) != null)
                {
                    rs.Angle = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("focus")) != null)
                {
                    int value;
                    if(int.TryParse(temp.Trim(), out value))
                    {
                        if(value <=100 && value >=-100)
                        {
                            rs.Focus = value;
                        }else
                        {
                            rs.Focus = 0;
                        }
                    }else
                    {
                        rs.Focus = 0;
                    }
                }

                if ((temp = reader.GetAttribute("focussize")) != null)
                {
                    rs.FocusSize = GetPointFromString(temp, 0, 0);
                }

                if ((temp = reader.GetAttribute("focusposition")) != null)
                {
                    rs.FocusPosition = GetPointFromString(temp, 0, 0);
                }

                if ((temp = reader.GetAttribute("method")) != null)
                {
                    var delimiters = new[] {' '};
                    var listtemp = temp.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                    var rstemp = "";

                    for (int i = 0; i < listtemp.Length;i++ )
                    {
                        var zzz = listtemp[i].Trim().ToLower();
                        if(zzz.Equals("sigma") || zzz.Equals("linear") || zzz.Equals("none") || zzz.Equals("any"))
                        {
                            rstemp += zzz + " ";
                        }
                    }

                    if(rstemp.Trim().Equals(""))
                    {
                        rstemp = "sigma";
                    }
                    rs.Method = rstemp.Trim();
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
            return rs;
        }
        #endregion

        #region READSTROKE
        private static VStroke ReadStroke(XmlReader reader)
        {
            var rs = new VStroke();

            try
            {
                string temp;

                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                if ((temp = reader.GetAttribute("on")) != null)
                {
                    rs.On = GetTrueFalseStringValue(temp, true);
                }

                if ((temp = reader.GetAttribute("weight")) != null)
                {
                    rs.Weight = GetIntegerFromString(temp, 1);
                }

                if ((temp = reader.GetAttribute("color")) != null)
                {
                    rs.Color = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                }

                if ((temp = reader.GetAttribute("style")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "single":
                            rs.Style = temp;
                            break;
                        case "thinthin":
                            rs.Style = temp;
                            break;
                        case "thinthick":
                            rs.Style = temp;
                            break;
                        case "thickthin":
                            rs.Style = temp;
                            break;
                        case "thickbetweenthin":
                            rs.Style = temp;
                            break;
                        default:
                            rs.Style = "single";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("miterlimit")) != null)
                {
                    rs.MiterLimit = GetFloatFromString(temp, 8.0f);
                }

                if ((temp = reader.GetAttribute("joinstyle")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "round":
                            rs.JoinStyle = temp;
                            break;
                        case "bevel":
                            rs.JoinStyle = temp;
                            break;
                        case "miter":
                            rs.JoinStyle = temp;
                            break;
                        default:
                            rs.JoinStyle = "round";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("endcap")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "round":
                            rs.EndCap = temp;
                            break;
                        case "flat":
                            rs.EndCap = temp;
                            break;
                        case "square":
                            rs.EndCap = temp;
                            break;
                        default:
                            rs.EndCap = "round";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("dashstyle")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "solid":
                            rs.DashStyle = temp;
                            break;
                        case "dot":
                            rs.DashStyle = temp;
                            break;
                        case "dash":
                            rs.DashStyle = temp;
                            break;
                        case "longdash":
                            rs.DashStyle = temp;
                            break;
                        case "longdashdot":
                            rs.DashStyle = temp;
                            break;
                        case "longdashdotdot":
                            rs.DashStyle = temp;
                            break;
                        default:
                            rs.DashStyle = temp;
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("filltype")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "solid":
                            rs.FillType = temp;
                            break;
                        case "tile":
                            rs.FillType = temp;
                            break;
                        case "pattern":
                            rs.FillType = temp;
                            break;
                        case "frame":
                            rs.FillType = temp;
                            break;
                        default:
                            rs.FillType = "solid";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("src")) != null)
                {
                    rs.Src = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("imagesize")) != null)
                {
                    rs.ImageSize = GetPointFromString(temp, int.MinValue, int.MinValue);

                }

                if ((temp = reader.GetAttribute("imagealignshape")) != null)
                {
                    rs.ImageAlignShape = GetTrueFalseStringValue(temp, true);
                }

                if ((temp = reader.GetAttribute("color2")) != null)
                {
                    rs.Color2 = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("startarrow")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "none":
                            rs.StartArrow = temp;
                            break;
                        case "block":
                            rs.StartArrow = temp;
                            break;
                        case "classic":
                            rs.StartArrow = temp;
                            break;
                        case "diamond":
                            rs.StartArrow = temp;
                            break;
                        case "oval":
                            rs.StartArrow = temp;
                            break;
                        case "open":
                            rs.StartArrow = temp;
                            break;
                        case "chevron":
                            rs.StartArrow = temp;
                            break;
                        case "doublechevron":
                            rs.StartArrow = temp;
                            break;
                        default:
                            rs.StartArrow = "none";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("startarrowwidth")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "narrow":
                            rs.StartArrowWidth = temp;
                            break;
                        case "medium":
                            rs.StartArrowWidth = temp;
                            break;
                        case "wide":
                            rs.StartArrowWidth = temp;
                            break;
                        default:
                            rs.StartArrowWidth = "medium";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("startarrowlength")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "narrow":
                            rs.StartArrowLength = temp;
                            break;
                        case "medium":
                            rs.StartArrowLength = temp;
                            break;
                        case "wide":
                            rs.StartArrowLength = temp;
                            break;
                        default:
                            rs.StartArrowLength = "medium";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("endarrow")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "none":
                            rs.EndArrow = temp;
                            break;
                        case "block":
                            rs.EndArrow = temp;
                            break;
                        case "classic":
                            rs.EndArrow = temp;
                            break;
                        case "diamond":
                            rs.EndArrow = temp;
                            break;
                        case "oval":
                            rs.EndArrow = temp;
                            break;
                        case "open":
                            rs.EndArrow = temp;
                            break;
                        case "chevron":
                            rs.EndArrow = temp;
                            break;
                        case "doublechevron":
                            rs.EndArrow = temp;
                            break;
                        default:
                            rs.EndArrow = "none";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("endarrowwidth")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "narrow":
                            rs.EndArrowWidth = temp;
                            break;
                        case "medium":
                            rs.EndArrowWidth = temp;
                            break;
                        case "wide":
                            rs.EndArrowWidth = temp;
                            break;
                        default:
                            rs.EndArrowWidth = "medium";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("endarrowlength")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "narrow":
                            rs.EndArrowLength = temp;
                            break;
                        case "medium":
                            rs.EndArrowLength = temp;
                            break;
                        case "wide":
                            rs.EndArrowLength = temp;
                            break;
                        default:
                            rs.EndArrowLength = "medium";
                            break;
                    }
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
            return rs;
        }
        #endregion

        #region READSHADOW
        private static VShadow ReadShadow(XmlReader reader)
        {
             var rs = new VShadow();

            try
            {
                string temp;

                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                if ((temp = reader.GetAttribute("on")) != null)
                {
                    rs.On = GetTrueFalseStringValue(temp, true);
                }

                if ((temp = reader.GetAttribute("type")) != null)
                {
                    switch (temp.Trim())
                    {
                        case "single":
                            rs.Type = temp;
                            break;
                        case "double":
                            rs.Type = temp;
                            break;
                        case "emboss":
                            rs.Type = temp;
                            break;
                        case "perspective":
                            rs.Type = temp;
                            break;
                        default:
                            rs.Type = "single";
                            break;
                    }
                }

                if ((temp = reader.GetAttribute("obscured")) != null)
                {
                    rs.Obscured = GetTrueFalseStringValue(temp, false);
                }

                if ((temp = reader.GetAttribute("color")) != null)
                {
                    rs.Color = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("opacity")) != null)
                {
                    var opac = GetFloatFromString(temp, 1.0f);
                    if (opac < 0.0f)
                    {
                        opac = 0.0f;
                    }

                    if (opac > 1.0f)
                    {
                        opac = 1.0f;
                    }
                    rs.Opacity = opac;
                    
                }

                if ((temp = reader.GetAttribute("offset")) != null)
                {
                    rs.Offset = GetPointFromString(temp, 2, 2);
                }

                if ((temp = reader.GetAttribute("color2")) != null)
                {
                    rs.Color2 = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("offset2")) != null)
                {
                    rs.Offset2 = GetPointFromString(temp, 0, 0);
                }

                if ((temp = reader.GetAttribute("origin")) != null)
                {
                    rs.Origin = GetPointFromString(temp, 0, 0);
                }

                if ((temp = reader.GetAttribute("matrix")) != null)
                {
                    rs.Matrix = RemoveMulipleSpaces(temp);
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
            return rs;
        }
        #endregion

        #region READTEXTBOX
        private static VTextBox ReadTextBox(XmlReader reader)
        {
            var rs = new VTextBox();

            try
            {
                string temp;

                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
            return rs;
        }
        #endregion

        #region READTEXTPATH
        private static VTextPath ReadTextPath(XmlReader reader)
        {
            var rs = new VTextPath();

            try
            {
                string temp;

                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                if ((temp = reader.GetAttribute("style")) != null)
                {
                    rs.Style = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("on")) != null)
                {
                    rs.On = GetTrueFalseStringValue(temp, false);
                }

                if ((temp = reader.GetAttribute("fitshape")) != null)
                {
                    rs.FitShape = GetTrueFalseStringValue(temp, false);
                }

                if ((temp = reader.GetAttribute("fitpath")) != null)
                {
                    rs.FitPath = GetTrueFalseStringValue(temp, false);
                }

                if ((temp = reader.GetAttribute("trim")) != null)
                {
                    rs.Trim = GetTrueFalseStringValue(temp, false);
                }

                if ((temp = reader.GetAttribute("xscale")) != null)
                {
                    rs.XScale = GetTrueFalseStringValue(temp, false);
                }

                if ((temp = reader.GetAttribute("string")) != null)
                {
                    rs.String = RemoveMulipleSpaces(temp);
                }

            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
            return rs;
        }

        #endregion

        #region READIMAGEDATA
        private static VImageData ReadImageData(XmlReader reader)
        {
            var rs = new VImageData();

            try
            {
                string temp;

                if ((temp = reader.GetAttribute("id")) != null)
                {
                    rs.Id = temp.Trim();
                }

                if ((temp = reader.GetAttribute("src")) != null)
                {
                    rs.Src = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("cropleft")) != null)
                {
                    rs.CropLeft = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("croptop")) != null)
                {
                    rs.CropTop = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("cropright")) != null)
                {
                    rs.CropRight = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("cropbottom")) != null)
                {
                    rs.CropBottom = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("gain")) != null)
                {
                    rs.Gain = GetIntegerFromString(temp, 1);
                }

                if ((temp = reader.GetAttribute("blacklevel")) != null)
                {
                    rs.BlackLevel = GetIntegerFromString(temp, 0);
                }

                if ((temp = reader.GetAttribute("gamma")) != null)
                {
                    rs.Gamma = GetIntegerFromString(temp, 1);
                }

                if ((temp = reader.GetAttribute("chromakey")) != null)
                {
                    rs.Chromakey = RemoveMulipleSpaces(temp);
                }

                if ((temp = reader.GetAttribute("grayscale")) != null)
                {
                    rs.GrayScale = GetTrueFalseStringValue(temp, false);
                }

                if ((temp = reader.GetAttribute("bilevel")) != null)
                {
                    rs.Bilevel = GetTrueFalseStringValue(temp, false);
                }
            }
            catch (ArgumentNullException)
            {

            }
            catch (InvalidOperationException)
            {

            }
            return rs;
        }
        #endregion

        #region HELPER
        private static Point GetPointFromString(String strPoint, int defaultX, int defaultY)
        {
            var rs = new Point {X = defaultX, Y = defaultY};
            if (strPoint.Equals("null")) return rs;

            if(strPoint.Equals("auto"))
            {
                rs.X = int.MinValue;
                rs.Y = int.MinValue;
                return rs;
            }

            if(strPoint.Equals("center"))
            {
                rs.X = int.MaxValue;
                rs.Y = int.MaxValue;
                return rs;
            }

            int index = -1;
            
            var index1 = strPoint.Trim().IndexOf(",", StringComparison.Ordinal);
            var index2 = strPoint.Trim().IndexOf(" ", StringComparison.Ordinal);
            if(index1 > 0)
            {
                index = index1;
            }else if(index2 > 0)
            {
                index = index2;
            }
            if(index>0)
            {
                var first = strPoint.Trim().Substring(0, index).Trim();
                var second = strPoint.Trim().Substring(index+1).Trim();

                int intFirst, intSecond;

                if(first.Contains("pt"))
                {
                    first = first.Substring(0, first.IndexOf("pt", StringComparison.Ordinal));
                }

                if (second.Contains("pt"))
                {
                    second = second.Substring(0, second.IndexOf("pt", StringComparison.Ordinal));
                }

                if (!int.TryParse(first, out intFirst))
                {
                    return rs;
                }
                

                if (!int.TryParse(second, out intSecond))
                {
                    return rs;
                }

                rs.X = intFirst;
                rs.Y = intSecond;
            }
            return rs;
        }

        private static string RemoveMulipleSpaces(string str)
        {
            var cleanedString = Regex.Replace(str, @"\s+", " ");
            return cleanedString;
        }

        private static int GetIntegerFromString(string str, int defaultvalue)
        {
            var strint = str;
            if (str.Contains("pt"))
            {
                strint = str.Substring(0, str.Length - 2);
            }
            int realint;
            return int.TryParse(strint.Trim(), out realint) ? realint : defaultvalue; 
        }

        private static float GetFloatFromString(string str, float defaultvalue)
        {
            var strfloat = str;
            if (str.Contains("pt"))
            {
                strfloat = str.Substring(0, str.Length - 2);
            }
            float realint;
            return float.TryParse(strfloat.Trim(), out realint) ? realint : defaultvalue;
        }

        private static Color GetColorFromRgbString(string color)
        {
            var numbers = Regex.Split(color, @"\D+");
            if(numbers.Length>=3)
            {
                int r, g, b;
                if(int.TryParse(numbers[0], out r) && int.TryParse(numbers[1], out g) && int.TryParse(numbers[2], out b))
                {
                    Color rs = Color.FromArgb(255, r, g, b);
                    return rs;
                }
                return Color.FromArgb(255, 128, 128, 128);
            }
            return Color.FromArgb(255, 128, 128, 128);
        }

        private static Color GetColorFromString(string color)
        {
            Color rs;
            switch (color.Trim().ToLower())
            {
                case "none":
                    rs = Color.FromArgb(0, 0, 0, 0);
                    break;
                case "transparent":
                    rs = Color.FromArgb(0, 0, 0, 0);
                    break;
                case "black":
                    rs = Color.FromArgb(255, 0, 0, 0);
                    break;
                case "silver":
                    rs = Color.FromArgb(255, 192, 192, 192);
                    break;
                case "gray":
                    rs = Color.FromArgb(255, 80, 80, 80);
                    break;
                case "white":
                    rs = Color.FromArgb(255, 255, 255, 255);
                    break;
                case "maroon":
                    rs = Color.FromArgb(255, 80, 0, 0);
                    break;
                case "red":
                    rs = Color.FromArgb(255, 255, 0, 0);
                    break;
                case "purple":
                    rs = Color.FromArgb(255, 80, 0, 80);
                    break;
                case "puchsia":
                    rs = Color.FromArgb(255, 255, 0, 255);
                    break;
                case "green":
                    rs = Color.FromArgb(255, 0, 80, 0);
                    break;
                case "lime":
                    rs = Color.FromArgb(255, 0, 255, 0);
                    break;
                case "olive":
                    rs = Color.FromArgb(255, 80, 80, 0);
                    break;
                case "yellow":
                    rs = Color.FromArgb(255, 255, 255, 0);
                    break;
                case "navy":
                    rs = Color.FromArgb(255, 0, 0, 80);
                    break;
                case "blue":
                    rs = Color.FromArgb(255, 0, 0, 255);
                    break;
                case "teal":
                    rs = Color.FromArgb(255, 0, 80, 80);
                    break;
                case "aqua":
                    rs = Color.FromArgb(255, 0, 255, 255);
                    break;
                default:
                    try
                    {
                        rs = ColorTranslator.FromHtml(color);
                    }
                    catch (Exception)
                    {
                        rs = Color.FromArgb(0, 0, 0, 0);
                    }
                    break;
            }

            return rs;
        }

        private static bool CheckColorFromString(string color)
        {
            bool rs = true;
            switch (color.Trim().ToLower())
            {
                case "none":
                    break;
                case "transparent":
                    break;
                case "black":
                    break;
                case "silver":
                    break;
                case "gray":
                    break;
                case "white":
                    break;
                case "maroon":
                    break;
                case "red":
                    break;
                case "purple":
                    break;
                case "puchsia":
                    break;
                case "green":
                    break;
                case "lime":
                    break;
                case "olive":
                    break;
                case "yellow":
                    break;
                case "navy":
                    break;
                case "blue":
                    break;
                case "teal":
                    break;
                case "aqua":
                    break;
                default:
                    try
                    {
                        ColorTranslator.FromHtml(color);
                    }
                    catch (Exception)
                    {
                        rs = false;
                    }
                    break;
            }

            return rs;
        }

        private static bool GetTrueFalseStringValue(string str, bool def)
        {
            var trueString = str.Trim();
            if (trueString.ToLower().Equals("true") || trueString.ToLower().Equals("t"))
            {
                return true;
            }
            if (trueString.ToLower().Equals("false") || trueString.ToLower().Equals("f"))
            {
                return true;
            }

            return def;
        }
        #endregion

        public static bool WriteFile(string fileDirvsName, List<VObject> listObjects)
        {
            var settings = new XmlWriterSettings {Indent = true, IndentChars = "\t"};
           
            try
            {
                using (var writer = XmlWriter.Create(fileDirvsName, settings))
                {
                    writer.WriteStartDocument();

                    foreach (var t in listObjects)
                    {
                        if (t is VShape)
                        {
                            WriteShape(writer, t as VShape);
                        }
                        else if (t is VShapeType)
                        {
                            WriteShapeType(writer, t as VShapeType);
                        }
                        else if (t is VGroup)
                        {
                            WriteGroup(writer, t as VGroup);
                        }
                        else if (t is VLine)
                        {
                            WriteLine(writer, t as VLine);
                        }
                        else if (t is VPolyLine)
                        {
                            WritePolyLine(writer, t as VPolyLine);
                        }
                        else if (t is VCurve)
                        {
                            WriteCurve(writer, t as VCurve);
                        }
                        else if (t is VRect)
                        {
                            WriteRect(writer, t as VRect);
                        }
                        else if (t is VRoundRect)
                        {
                            WriteRoundRect(writer, t as VRoundRect);
                        }
                        else if (t is VOval)
                        {
                            WriteOval(writer, t as VOval);
                        }
                        else if (t is VArc)
                        {
                            WriteArc(writer, t as VArc);
                        }
                        else if (t is VImage)
                        {
                            WriteImage(writer, t as VImage);
                        }
                        else if (t is VBackground)
                        {
                            WriteBackground(writer, t as VBackground);
                        }
                    }

                    writer.WriteEndDocument();
                }
                
            }
            catch (Exception e)
            {
                MessageBox.Show("Error : " + e.Message);
                return false;
            }
            return true;
        }

        private static void WriteShape(XmlWriter wt, VShape shape)
        {
            var def = new VShape();

            wt.WriteStartElement("v", "shape", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            if(shape.Type != null && !shape.Type.Equals(def.Type))
            {
                wt.WriteAttributeString("type", shape.Type);
            }

            if (shape.Adj != null && !shape.Adj.Equals(def.Adj))
            {
                wt.WriteAttributeString("adj", shape.Adj);
            }

            if (shape.Path != null && !shape.Path.Equals(def.Path))
            {
                wt.WriteAttributeString("path", shape.Path);
            }

            if (shape.V != null && !shape.V.Equals(def.V))
            {
                wt.WriteAttributeString("v", shape.V);
            }

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if(t is VPath)
                {
                    WritePath(wt,t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();

        }

        private static void WriteShapeType(XmlWriter wt, VShapeType shape)
        {
            var def = new VShapeType();

            wt.WriteStartElement("v", "shapetype", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            if (shape.Adj != null && !shape.Adj.Equals(def.Adj))
            {
                wt.WriteAttributeString("adj", shape.Adj);
            }

            if (shape.Path != null && !shape.Path.Equals(def.Path))
            {
                wt.WriteAttributeString("path", shape.Path);
            }

            if (shape.V != null && !shape.V.Equals(def.V))
            {
                wt.WriteAttributeString("v", shape.V);
            }

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VPath)
                {
                    WritePath(wt, t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();
        }

        private static void WriteGroup(XmlWriter wt, VGroup shape)
        {
            var def = new VGroup();

            wt.WriteStartElement("v", "group", NAMESPACE);

            //ATTRIBUTES

            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (shape.Href != null && !shape.Href.Equals(def.Href))
            {
                wt.WriteAttributeString("href", shape.Href);
            }

            if (shape.Target != null && !shape.Target.Equals(def.Target))
            {
                wt.WriteAttributeString("target", shape.Target);
            }

            if (shape.Class != null && !shape.Class.Equals(def.Class))
            {
                wt.WriteAttributeString("class", shape.Class);
            }

            if (shape.Title != null && !shape.Title.Equals(def.Title))
            {
                wt.WriteAttributeString("title", shape.Title);
            }

            if (shape.Alt != null && !shape.Alt.Equals(def.Alt))
            {
                wt.WriteAttributeString("alt", shape.Alt);
            }

            if (shape.Style != null && !shape.Style.Equals(def.Style))
            {
                wt.WriteAttributeString("style", shape.Style);
            }

            if (!shape.CoordSize.Equals(def.CoordSize))
            {
                wt.WriteAttributeString("coordsize", GetStringFromPoint(shape.CoordSize));
            }

            if (!shape.CoordOrigin.Equals(def.CoordOrigin))
            {
                wt.WriteAttributeString("coordorigin", GetStringFromPoint(shape.CoordOrigin));
            }

            if (shape.WrapCoords != null && !shape.WrapCoords.Equals(def.WrapCoords))
            {
                wt.WriteAttributeString("wrapcoords", shape.WrapCoords);
            }


            //SUB ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VShape)
                {
                    WriteShape(wt, t as VShape);
                }
                else if (t is VShapeType)
                {
                    WriteShapeType(wt, t as VShapeType);
                }
                else if (t is VGroup)
                {
                    WriteGroup(wt, t as VGroup);
                }
                else if (t is VLine)
                {
                    WriteLine(wt, t as VLine);
                }
                else if (t is VPolyLine)
                {
                    WritePolyLine(wt, t as VPolyLine);
                }
                else if (t is VCurve)
                {
                    WriteCurve(wt, t as VCurve);
                }
                else if (t is VRect)
                {
                    WriteRect(wt, t as VRect);
                }
                else if (t is VRoundRect)
                {
                    WriteRoundRect(wt, t as VRoundRect);
                }
                else if (t is VOval)
                {
                    WriteOval(wt, t as VOval);
                }
                else if (t is VArc)
                {
                    WriteArc(wt, t as VArc);
                }
                else if (t is VImage)
                {
                    WriteImage(wt, t as VImage);
                }
            }

            wt.WriteEndElement();
        }

        private static void WriteLine(XmlWriter wt, VLine shape)
        {
            var def = new VLine();

            wt.WriteStartElement("v", "line", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            if (!shape.From.Equals(def.From))
            {
                wt.WriteAttributeString("from", GetStringFromPoint(shape.From));
            }

            if (!shape.To.Equals(def.To))
            {
                wt.WriteAttributeString("to", GetStringFromPoint(shape.To));
            }

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VPath)
                {
                    WritePath(wt, t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();
        }

        private static void WritePolyLine(XmlWriter wt, VPolyLine shape)
        {
            var def = new VPolyLine();

            wt.WriteStartElement("v", "polyline", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            if (shape.Points != null && !shape.Points.Equals(def.Points))
            {
                var rs = shape.Points.Aggregate("", (current, t) => current + (t.X + " " + t.Y));
                wt.WriteAttributeString("points", rs);
            }

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VPath)
                {
                    WritePath(wt, t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();
        }

        private static void WriteCurve(XmlWriter wt, VCurve shape)
        {
            var def = new VCurve();

            wt.WriteStartElement("v", "curve", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            if (!shape.From.Equals(def.From))
            {
                wt.WriteAttributeString("from", GetStringFromPoint(shape.From));
            }

            if (!shape.Control1.Equals(def.Control1))
            {
                wt.WriteAttributeString("control1", GetStringFromPoint(shape.Control1));
            }

            if (!shape.Control2.Equals(def.Control2))
            {
                wt.WriteAttributeString("control2", GetStringFromPoint(shape.Control2));
            }

            if (!shape.To.Equals(def.To))
            {
                wt.WriteAttributeString("to", GetStringFromPoint(shape.To));
            }

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VPath)
                {
                    WritePath(wt, t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();
        }

        private static void WriteRect(XmlWriter wt, VRect shape)
        {
            wt.WriteStartElement("v", "rect", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VPath)
                {
                    WritePath(wt, t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();
        }

        private static void WriteRoundRect(XmlWriter wt, VRoundRect shape)
        {
            var def = new VRoundRect();

            wt.WriteStartElement("v", "roundrect", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            if (!shape.ArcSize.Equals(def.ArcSize))
            {
                wt.WriteAttributeString("arcsize", shape.ArcSize + "");
            }

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VPath)
                {
                    WritePath(wt, t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();
        }

        private static void WriteOval(XmlWriter wt, VOval shape)
        {
            wt.WriteStartElement("v", "oval", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VPath)
                {
                    WritePath(wt, t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();
        }

        private static void WriteArc(XmlWriter wt, VArc shape)
        {
            var def = new VArc();

            wt.WriteStartElement("v", "arc", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            if (!shape.StartAngle.Equals(def.StartAngle))
            {
                wt.WriteAttributeString("startangle", shape.StartAngle + "");
            }

            if (!shape.EndAngle.Equals(def.EndAngle))
            {
                wt.WriteAttributeString("endangle", shape.EndAngle + "");
            }

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VPath)
                {
                    WritePath(wt, t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();
        }

        private static void WriteImage(XmlWriter wt, VImage shape)
        {
            var def = new VImage();

            wt.WriteStartElement("v", "image", NAMESPACE);

            //ATTRIBUTES
            WriteShapeBase(wt, shape);

            if (shape.Src != null && !shape.Src.Equals(def.Src))
            {
                wt.WriteAttributeString("src", shape.Src);
            }

            if (!shape.CropLeft.Equals(def.CropLeft))
            {
                wt.WriteAttributeString("cropleft", shape.CropLeft + "");
            }

            if (!shape.CropTop.Equals(def.CropTop))
            {
                wt.WriteAttributeString("croptop", shape.CropTop + "");
            }

            if (!shape.CropRight.Equals(def.CropRight))
            {
                wt.WriteAttributeString("cropright", shape.CropRight + "");
            }

            if (!shape.CropBottom.Equals(def.CropBottom))
            {
                wt.WriteAttributeString("cropbottom", shape.CropBottom + "");
            }

            if (!shape.Gain.Equals(def.Gain))
            {
                wt.WriteAttributeString("gain", shape.Gain + "");
            }

            if (!shape.BlackLevel.Equals(def.BlackLevel))
            {
                wt.WriteAttributeString("blacklevel", shape.BlackLevel + "");
            }

            if (!shape.Gamma.Equals(def.Gamma))
            {
                wt.WriteAttributeString("gamma", shape.Gamma + "");
            }

            if (shape.EmbossColor != null && !shape.EmbossColor.Equals(def.EmbossColor))
            {
                wt.WriteAttributeString("embosscolor", shape.EmbossColor);
            }

            if (!shape.GrayScale.Equals(def.GrayScale))
            {
                wt.WriteAttributeString("grayscale", shape.GrayScale + "");
            }

            if (!shape.Bilevel.Equals(def.Bilevel))
            {
                wt.WriteAttributeString("bilevel", shape.Bilevel.ToString().ToLower());
            }

            //SUB_ELEMENTS
            foreach (var t in shape.Elements)
            {
                if (t is VPath)
                {
                    WritePath(wt, t as VPath);
                }
                else if (t is VFormulas)
                {
                    WriteFomulas(wt, t as VFormulas);
                }
                else if (t is VHandles)
                {
                    WriteHandles(wt, t as VHandles);
                }
                else if (t is VFill)
                {
                    WriteFill(wt, t as VFill);
                }
                else if (t is VStroke)
                {
                    WriteStroke(wt, t as VStroke);
                }
                else if (t is VShadow)
                {
                    WriteShadow(wt, t as VShadow);
                }
                else if (t is VTextBox)
                {
                    WriteTextBox(wt, t as VTextBox);
                }
                else if (t is VTextPath)
                {
                    WriteTextPath(wt, t as VTextPath);
                }
                else if (t is VImageData)
                {
                    WriteImageData(wt, t as VImageData);
                }
            }

            wt.WriteEndElement();
        }

        private static void WriteBackground(XmlWriter wt, VBackground shape)
        {
            var def = new VBackground();

            wt.WriteStartElement("v", "background", NAMESPACE);

            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (!shape.Fill.Equals(def.Fill))
            {
                wt.WriteAttributeString("fill", shape.Fill.ToString().ToLower());
            }

            if (shape.FillColor != null && !shape.FillColor.Equals(def.FillColor))
            {
                wt.WriteAttributeString("fillcolor", shape.FillColor);
            }

            //SUB_ELEMENTS
            if(shape.FillElement != null)
            {
                WriteFill(wt,shape.FillElement);
            }

            wt.WriteEndElement();
        }

        private static void WriteShapeBase(XmlWriter wt, VShapeBase shape)
        {
            var def = new VShapeBase();
            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (shape.Href != null && !shape.Href.Equals(def.Href))
            {
                wt.WriteAttributeString("href", shape.Href);
            }

            if (shape.Target != null && !shape.Target.Equals(def.Target))
            {
                wt.WriteAttributeString("target", shape.Target);
            }

            if (shape.Class != null && !shape.Class.Equals(def.Class))
            {
                wt.WriteAttributeString("class", shape.Class);
            }

            if (shape.Title != null && !shape.Title.Equals(def.Title))
            {
                wt.WriteAttributeString("title", shape.Title);
            }

            if (shape.Alt != null && !shape.Alt.Equals(def.Alt))
            {
                wt.WriteAttributeString("alt", shape.Alt);
            }

            if (shape.Style != null && !shape.Style.Equals(def.Style))
            {
                wt.WriteAttributeString("style", shape.Style);
            }

            if (!shape.Opacity.Equals(def.Opacity))
            {
                wt.WriteAttributeString("opacity", shape.Opacity + "");
            }

            if (shape.Chromakey != null && !shape.Chromakey.Equals(def.Chromakey))
            {
                wt.WriteAttributeString("chromakey", shape.Chromakey);
            }

            if (!shape.Stroke.Equals(def.Stroke))
            {
                wt.WriteAttributeString("stroke", shape.Stroke.ToString().ToLower());
            }

            if (shape.StrokeColor != null && !shape.StrokeColor.Equals(def.StrokeColor))
            {
                wt.WriteAttributeString("strokecolor", shape.StrokeColor);
            }

            if (!shape.StrokeWeight.Equals(def.StrokeWeight))
            {
                wt.WriteAttributeString("strokeweight", shape.StrokeWeight + "");
            }

            if (!shape.Fill.Equals(def.Fill))
            {
                wt.WriteAttributeString("fill", shape.Fill.ToString().ToLower());
            }

            if (shape.FillColor != null && !shape.FillColor.Equals(def.FillColor))
            {
                wt.WriteAttributeString("fillcolor", shape.FillColor);
            }

            if (!shape.Print.Equals(def.Print))
            {
                wt.WriteAttributeString("print", shape.Print.ToString().ToLower());
            }

            if (shape.CoordSize != null && !shape.CoordSize.Equals(def.CoordSize))
            {
                wt.WriteAttributeString("coordsize", GetStringFromPoint(shape.CoordSize));
            }

            if (shape.CoordOrigin != null && !shape.CoordOrigin.Equals(def.CoordOrigin))
            {
                wt.WriteAttributeString("coordorigin", GetStringFromPoint(shape.CoordOrigin));
            }

            if (shape.WrapCoords != null && !shape.WrapCoords.Equals(def.WrapCoords))
            {
                wt.WriteAttributeString("wrapcoords", shape.WrapCoords);
            }
        }
        
        private static void WritePath(XmlWriter wt, VPath shape)
        {
            wt.WriteStartElement("v", "path", NAMESPACE);
            var def = new VPath();
            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (shape.V != null && !shape.V.Equals(def.V))
            {
                wt.WriteAttributeString("v", shape.V);
            }

            if (!shape.Limo.Equals(def.Limo))
            {
                wt.WriteAttributeString("limo", GetStringFromPoint(shape.Limo));
            }

            if (!shape.FillOk.Equals(def.FillOk))
            {
                wt.WriteAttributeString("fillok", shape.FillOk.ToString().ToLower());
            }

            if (!shape.StrokeOk.Equals(def.StrokeOk))
            {
                wt.WriteAttributeString("strokeok", shape.StrokeOk.ToString().ToLower());
            }

            if (!shape.ShadowOk.Equals(def.ShadowOk))
            {
                wt.WriteAttributeString("shadowok", shape.ShadowOk.ToString().ToLower());
            }

            if (!shape.ArrowOk.Equals(def.ArrowOk))
            {
                wt.WriteAttributeString("arrowok", shape.ArrowOk.ToString().ToLower());
            }

            if (!shape.GradientShapeOK.Equals(def.GradientShapeOK))
            {
                wt.WriteAttributeString("gradientshapeok", shape.GradientShapeOK.ToString().ToLower());
            }

            if (!shape.TextPathOK.Equals(def.TextPathOK))
            {
                wt.WriteAttributeString("textpathok", shape.TextPathOK.ToString().ToLower());
            }

            if (shape.TextBoxRect != null && !shape.TextBoxRect.Equals(def.TextBoxRect))
            {
                wt.WriteAttributeString("textboxrect", shape.TextBoxRect);
            }
            wt.WriteEndElement();
        }

        private static void WriteFomulas(XmlWriter wt, VFormulas shape)
        {
            wt.WriteStartElement("v", "formulas", NAMESPACE);

            foreach (var t in shape.Elements)
            {
                wt.WriteStartElement("f");
                wt.WriteAttributeString("eqn",t.eqn);
                wt.WriteEndElement();
            }

            wt.WriteEndElement();
        }

        private static void WriteHandles(XmlWriter wt, VHandles shape)
        {
            wt.WriteStartElement("v", "handles", NAMESPACE);
            var def = new VH();
            foreach (var t in shape.Elements)
            {
                wt.WriteStartElement("h");

                if (!t.Position.Equals(def.Position))
                {
                    wt.WriteAttributeString("position", GetStringFromPoint(t.Position));
                }

                if (!t.Polar.Equals(def.Polar))
                {
                    wt.WriteAttributeString("polar", GetStringFromPoint(t.Polar));
                }

                if (!t.Map.Equals(def.Map))
                {
                    wt.WriteAttributeString("map", GetStringFromPoint(t.Map));
                }


                if (!t.InvX.Equals(def.InvX))
                {
                    wt.WriteAttributeString("invx", t.InvX.ToString().ToLower());
                }


                if (!t.InvY.Equals(def.InvY))
                {
                    wt.WriteAttributeString("invy", t.InvY.ToString().ToLower());
                }

                if (!t.Switch.Equals(def.Switch))
                {
                    wt.WriteAttributeString("switch", t.Switch.ToString().ToLower());
                }


                if (!t.XRange.Equals(def.XRange))
                {
                    wt.WriteAttributeString("xrange", GetStringFromPoint(t.XRange));
                }


                if (!t.YRange.Equals(def.YRange))
                {
                    wt.WriteAttributeString("yrange", GetStringFromPoint(t.YRange));
                }

                if (!t.RadiusRange.Equals(def.RadiusRange))
                {
                    wt.WriteAttributeString("radiusrange", GetStringFromPoint(t.RadiusRange));
                }
                
                wt.WriteEndElement();
            }
            wt.WriteEndElement();
        }

        private static void WriteFill(XmlWriter wt, VFill shape)
        {
            wt.WriteStartElement("v", "fill", NAMESPACE);
            var def = new VFill();
            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (shape.Type != null && !shape.Type.Equals(def.Type))
            {
                wt.WriteAttributeString("type", shape.Type);
            }

            if (!shape.On.Equals(def.On))
            {
                wt.WriteAttributeString("on", shape.On.ToString().ToLower());
            }

            if (shape.Color != null && !shape.Color.Equals(def.Color))
            {
                wt.WriteAttributeString("color", shape.Color);
            }

            if (!shape.Opacity.Equals(def.Opacity))
            {
                wt.WriteAttributeString("opacity", shape.Opacity + "");
            }

            if (shape.Color2 != null && !shape.Color2.Equals(def.Color2))
            {
                wt.WriteAttributeString("color2", shape.Color2);
            }

            if (shape.Src != null && !shape.Src.Equals(def.Src))
            {
                wt.WriteAttributeString("src", shape.Src);
            }

            if (!shape.Size.Equals(def.Size))
            {
                wt.WriteAttributeString("size", GetStringFromPoint(shape.Size));
            }

            if (!shape.Origin.Equals(def.Origin))
            {
                wt.WriteAttributeString("origin", GetStringFromPoint(shape.Origin));
            }

            if (!shape.Position.Equals(def.Position))
            {
                wt.WriteAttributeString("position", GetStringFromPoint(shape.Position));
            }

            if (shape.Aspect != null && !shape.Aspect.Equals(def.Aspect))
            {
                wt.WriteAttributeString("aspect", shape.Aspect);
            }

            if (!shape.AlignShape.Equals(def.AlignShape))
            {
                wt.WriteAttributeString("alignshape", shape.AlignShape.ToString().ToLower());
            }

            if (shape.Colors != null && !shape.Colors.Equals(def.Colors))
            {
                wt.WriteAttributeString("colors", shape.Colors);
            }

            if (!shape.Angle.Equals(def.Angle))
            {
                wt.WriteAttributeString("angle", shape.Angle + "");
            }

            if (!shape.Focus.Equals(def.Focus))
            {
                wt.WriteAttributeString("focus", shape.Focus + "");
            }

            if (!shape.FocusSize.Equals(def.FocusSize))
            {
                wt.WriteAttributeString("focussize", GetStringFromPoint(shape.FocusSize));
            }

            if (!shape.FocusPosition.Equals(def.FocusPosition))
            {
                wt.WriteAttributeString("focusposition", GetStringFromPoint(shape.FocusPosition));
            }

            if (shape.Method != null && !shape.Method.Equals(def.Method))
            {
                wt.WriteAttributeString("method", shape.Method);
            }

            wt.WriteEndElement();
        }

        private static void WriteStroke(XmlWriter wt, VStroke shape)
        {
            wt.WriteStartElement("v", "stroke", NAMESPACE);
            var def = new VStroke();
            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (!shape.On.Equals(def.On))
            {
                wt.WriteAttributeString("on", shape.On.ToString().ToLower());
            }

            if (!shape.Weight.Equals(def.Weight))
            {
                wt.WriteAttributeString("weight", shape.Weight + "");
            }

            if (shape.Color != null && !shape.Color.Equals(def.Color))
            {
                wt.WriteAttributeString("color", shape.Color);
            }

            if (!shape.Opacity.Equals(def.Opacity))
            {
                wt.WriteAttributeString("opacity", shape.Opacity + "");
            }

            if (shape.Style != null && !shape.Style.Equals(def.Style))
            {
                wt.WriteAttributeString("style", shape.Style);
            }

            if (!shape.MiterLimit.Equals(def.MiterLimit))
            {
                wt.WriteAttributeString("miterlimit", shape.MiterLimit + "");
            }

            if (shape.JoinStyle != null && !shape.JoinStyle.Equals(def.JoinStyle))
            {
                wt.WriteAttributeString("joinstyle", shape.JoinStyle);
            }

            if (shape.EndCap != null && !shape.EndCap.Equals(def.EndCap))
            {
                wt.WriteAttributeString("endcap", shape.EndCap);
            }

            if (shape.DashStyle != null && !shape.DashStyle.Equals(def.DashStyle))
            {
                wt.WriteAttributeString("dashstyle", shape.DashStyle);
            }

            if (shape.FillType != null && !shape.FillType.Equals(def.FillType))
            {
                wt.WriteAttributeString("filltype", shape.FillType);
            }

            if (shape.Src != null && !shape.Src.Equals(def.Src))
            {
                wt.WriteAttributeString("src", shape.Src);
            }

            if (!shape.ImageSize.Equals(def.ImageSize))
            {
                wt.WriteAttributeString("imagesize", GetStringFromPoint(shape.ImageSize));
            }

            if (!shape.ImageAlignShape.Equals(def.ImageAlignShape))
            {
                wt.WriteAttributeString("imagealignshape", shape.ImageAlignShape.ToString().ToLower());
            }

            if (shape.Color2 != null && !shape.Color2.Equals(def.Color2))
            {
                wt.WriteAttributeString("color2", shape.Color2);
            }

            if (shape.StartArrow != null && !shape.StartArrow.Equals(def.StartArrow))
            {
                wt.WriteAttributeString("startarrow", shape.StartArrow);
            }

            if (shape.StartArrowWidth != null && !shape.StartArrowWidth.Equals(def.StartArrowWidth))
            {
                wt.WriteAttributeString("startarrowwidth", shape.StartArrowWidth);
            }

            if (shape.StartArrowLength != null && !shape.StartArrowLength.Equals(def.StartArrowLength))
            {
                wt.WriteAttributeString("startarrowlength", shape.StartArrowLength);
            }

            if (shape.EndArrow != null && !shape.EndArrow.Equals(def.EndArrow))
            {
                wt.WriteAttributeString("endarrow", shape.EndArrow);
            }

            if (shape.EndArrowWidth != null && !shape.EndArrowWidth.Equals(def.EndArrowWidth))
            {
                wt.WriteAttributeString("endarrowwidth", shape.EndArrowWidth);
            }

            if (shape.EndArrowLength != null && !shape.EndArrowLength.Equals(def.EndArrowLength))
            {
                wt.WriteAttributeString("endarrowlength", shape.EndArrowLength);
            }

            wt.WriteEndElement();
        }

        private static void WriteShadow(XmlWriter wt, VShadow shape)
        {
            wt.WriteStartElement("v", "shadow", NAMESPACE);
            var def = new VShadow();
            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (!shape.On.Equals(def.On))
            {
                wt.WriteAttributeString("on", shape.On.ToString().ToLower());
            }

            if (shape.Type != null && !shape.Type.Equals(def.Type))
            {
                wt.WriteAttributeString("type", shape.Type);
            }

            if (!shape.Obscured.Equals(def.Obscured))
            {
                wt.WriteAttributeString("obscured", shape.Obscured.ToString().ToLower());
            }

            if (shape.Color != null && !shape.Color.Equals(def.Color))
            {
                wt.WriteAttributeString("color", shape.Color);
            }

            if (!shape.Opacity.Equals(def.Opacity))
            {
                wt.WriteAttributeString("opacity", shape.Opacity + "");
            }

            if (!shape.Offset.Equals(def.Offset))
            {
                wt.WriteAttributeString("offset", GetStringFromPoint(shape.Offset));
            }

            if (shape.Color2 != null && !shape.Color2.Equals(def.Color2))
            {
                wt.WriteAttributeString("color2", shape.Color2);
            }

            if (!shape.Offset2.Equals(def.Offset2))
            {
                wt.WriteAttributeString("offset2", GetStringFromPoint(shape.Offset2));
            }

            if (!shape.Origin.Equals(def.Origin))
            {
                wt.WriteAttributeString("origin", GetStringFromPoint(shape.Origin));
            }

            if (shape.Matrix != null && !shape.Matrix.Equals(def.Matrix))
            {
                wt.WriteAttributeString("matrix", shape.Matrix);
            }

            wt.WriteEndElement();
        }

        private static void WriteTextBox(XmlWriter wt, VTextBox shape)
        {
            wt.WriteStartElement("v", "textbox", NAMESPACE);
            var def = new VTextBox();
            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (shape.Style != null && !shape.Style.Equals(def.Style))
            {
                wt.WriteAttributeString("style", shape.Style);
            }

            wt.WriteEndElement();
        }

        private static void WriteTextPath(XmlWriter wt, VTextPath shape)
        {
            wt.WriteStartElement("v", "textpath", NAMESPACE);
            var def = new VTextPath();

            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (shape.Style != null && !shape.Style.Equals(def.Style))
            {
                wt.WriteAttributeString("style", shape.Style);
            }

            //==========

            if (!shape.On.Equals(def.On))
            {
                wt.WriteAttributeString("on", shape.On.ToString().ToLower());
            }

            if (!shape.FitShape.Equals(def.FitShape))
            {
                wt.WriteAttributeString("fitshape", shape.FitShape.ToString().ToLower());
            }

            if (!shape.FitPath.Equals(def.FitPath))
            {
                wt.WriteAttributeString("fitpath", shape.FitPath.ToString().ToLower());
            }

            if (!shape.Trim.Equals(def.Trim))
            {
                wt.WriteAttributeString("trim", shape.Trim.ToString().ToLower());
            }

            if (!shape.XScale.Equals(def.XScale))
            {
                wt.WriteAttributeString("xscale", shape.XScale.ToString().ToLower());
            }

            if (shape.String != null && !shape.String.Equals(def.String))
            {
                wt.WriteAttributeString("string", shape.String);
            }

            wt.WriteEndElement();
        }

        private static void WriteImageData(XmlWriter wt, VImageData shape)
        {
            wt.WriteStartElement("v", "imagedata", NAMESPACE);
            var def = new VImageData();

            if (shape.Id != null && !shape.Id.Equals(def.Id))
            {
                wt.WriteAttributeString("id", shape.Id);
            }

            if (shape.Src != null && !shape.Src.Equals(def.Src))
            {
                wt.WriteAttributeString("src", shape.Src);
            }

            if (!shape.CropLeft.Equals(def.CropLeft))
            {
                wt.WriteAttributeString("cropleft", shape.CropLeft + "");
            }

            if (!shape.CropTop.Equals(def.CropTop))
            {
                wt.WriteAttributeString("croptop", shape.CropTop + "");
            }

            if (!shape.CropRight.Equals(def.CropRight))
            {
                wt.WriteAttributeString("cropright", shape.CropRight + "");
            }

            if (!shape.CropBottom.Equals(def.CropBottom))
            {
                wt.WriteAttributeString("cropbottom", shape.CropBottom + "");
            }

            if (!shape.Gain.Equals(def.Gain))
            {
                wt.WriteAttributeString("gain", shape.Gain + "");
            }

            if (!shape.BlackLevel.Equals(def.BlackLevel))
            {
                wt.WriteAttributeString("blacklevel", shape.BlackLevel + "");
            }

            if (!shape.Gamma.Equals(def.Gamma))
            {
                wt.WriteAttributeString("gamma", shape.Gamma + "");
            }

            if (shape.Chromakey != null && !shape.Chromakey.Equals(def.Chromakey))
            {
                wt.WriteAttributeString("chromakey", shape.Chromakey);
            }

            if (!shape.GrayScale.Equals(def.GrayScale))
            {
                wt.WriteAttributeString("grayscale", shape.GrayScale.ToString().ToLower());
            }

            if (!shape.Bilevel.Equals(def.Bilevel))
            {
                wt.WriteAttributeString("bilevel", shape.Bilevel.ToString().ToLower());
            }

            wt.WriteEndElement();
        }

        private static string GetStringFromPoint(Point point)
        {
            if(point.X == int.MinValue && point.Y == int.MinValue)
            {
                return "null";
            }

            if(point.X == int.MaxValue && point.Y == int.MaxValue)
            {
                return "center";
            }

            return Convert.ToInt32(Math.Round(point.X, 0, MidpointRounding.ToEven)) + ", " + Convert.ToInt32(Math.Round(point.Y, 0, MidpointRounding.ToEven));
        }

        private static int[] GetIntFromStringListSepByComma(string str)
        {
            var numbers = new[] {0,0,0,0,0,0,0,0};
            if(String.IsNullOrEmpty(str))
            {
                return numbers;
            }
            var delimiters = new[] {" , ", " ,", ", ", ",", " "};
            var temp = str.Split(delimiters, StringSplitOptions.None);
            for(var i = 0; i<temp.Length; i++)
            {
                if(temp[i].Trim().Equals(""))
                {
                    numbers[i] = 0;
                }else
                {
                    int value;
                    if (!int.TryParse(temp[i].Trim(), out value)) continue;
                    if (i < 8)
                    {
                        numbers[i] = value;
                    }
                }
                
            }

            return numbers;
        } 

        private static string GetStringFromIntArray(int[] number)
        {
            if(number.Length > 0)
            {
                var tempstr = number[0] + "";
                for (var i = 1; i < number.Length; i++)
                {
                    tempstr = tempstr + ", " + number[i];
                }
                return tempstr;
            }
            return "";
        }

        public static IEnumerable<VCommand> GetVFromString(string str)
        {
            var cmds = new List<VCommand>();
            if (String.IsNullOrEmpty(str))
            {
                return cmds;
            }
            var delimiters = new[] { " , ", " ,", ", ", ",", " " };
            var temp = str.Split(delimiters, StringSplitOptions.None);

            foreach (var t in temp)
            {
                ReadVEle(t ,cmds, false);
            }

            //output check
            if (cmds.Count == 0) return cmds;

            for (var i = cmds.Count - 1 ; i >= 0; i--)
            {
                switch (cmds[i].Cmd)
                {
                    case "m":
                        if(cmds[i].CmdParams.Count<2)
                        {
                            cmds.RemoveAt(i);
                        }else if (cmds[i].CmdParams.Count > 2)
                        {
                            cmds.RemoveAt(i);
                        }
                        break;
                    case "l":
                        if (cmds[i].CmdParams.Count < 2)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count%2 != 0)
                        {
                            cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count-1);
                        }
                        break;
                    case "c":
                        if (cmds[i].CmdParams.Count < 6)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 6 != 0)
                        {
                            var tempcount = cmds[i].CmdParams.Count%6;
                            for (var j = 0; j < tempcount; j++)
                            {
                                cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                            }   
                        }
                        break;
                    case "x":
                        cmds[i].CmdParams.Clear();
                        break;
                    case "e":
                        cmds[i].CmdParams.Clear();
                        break;
                    case "t":
                        if (cmds[i].CmdParams.Count < 2)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count%2 != 0)
                        {
                            cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count-1);
                        }
                        break;
                    case "r":
                        if (cmds[i].CmdParams.Count < 2)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count%2 != 0)
                        {
                            cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count-1);
                        }
                        break;
                    case "v":
                        if (cmds[i].CmdParams.Count < 6)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 6 != 0)
                        {
                            var tempcount = cmds[i].CmdParams.Count % 6;
                            for (var j = 0; j < tempcount; j++)
                            {
                                cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                            }
                        }
                        break;
                    case "nf":
                        cmds[i].CmdParams.Clear();
                        break;
                    case "ns":
                        cmds[i].CmdParams.Clear();
                        break;
                    case "ae":
                        if (cmds[i].CmdParams.Count < 6)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 6 != 0)
                        {
                            var tempcount = cmds[i].CmdParams.Count % 6;
                            for (var j = 0; j < tempcount; j++)
                            {
                                cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                            }
                        }
                        break;
                    case "al":
                        if (cmds[i].CmdParams.Count < 6)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 6 != 0)
                        {
                            var tempcount = cmds[i].CmdParams.Count % 6;
                            for (var j = 0; j < tempcount; j++)
                            {
                                cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                            }
                        }
                        break;
                    case "at":
                        if (cmds[i].CmdParams.Count < 8)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 8 != 0)
                        {
                            var tempcount = cmds[i].CmdParams.Count % 8;
                            for (var j = 0; j < tempcount; j++)
                            {
                                cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                            }
                        }
                        break;
                    case "ar":
                        if (cmds[i].CmdParams.Count < 8)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 8 != 0)
                        {
                            var tempcount = cmds[i].CmdParams.Count % 8;
                            for (var j = 0; j < tempcount; j++)
                            {
                                cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                            }
                        }
                        break;
                    case "wa":
                        if (cmds[i].CmdParams.Count < 8)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 8 != 0)
                        {
                            var tempcount = cmds[i].CmdParams.Count % 8;
                            for (var j = 0; j < tempcount; j++)
                            {
                                cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                            }
                        }
                        break;
                    case "wr":
                        if (cmds[i].CmdParams.Count < 8)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 8 != 0)
                        {
                            var tempcount = cmds[i].CmdParams.Count % 8;
                            for (var j = 0; j < tempcount; j++)
                            {
                                cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                            }
                        }
                        break;
                    case "qx":
                        if (cmds[i].CmdParams.Count < 2)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 2 != 0)
                        {
                            cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                        }
                        break;
                    case "qy":
                        if (cmds[i].CmdParams.Count < 2)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 2 != 0)
                        {
                            cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                        }
                        break;
                    case "qb":
                        if (cmds[i].CmdParams.Count < 4)
                        {
                            cmds.RemoveAt(i);
                        }
                        else if (cmds[i].CmdParams.Count % 2 != 0)
                        {
                            cmds[i].CmdParams.RemoveAt(cmds[i].CmdParams.Count - 1);
                        }
                        break;
                }
            }

            return cmds;
        } 

        private static void ReadVEle(string param, List<VCommand> cmds, bool isSubString)
        {
            bool sub1Read = false, sub2Read = false;
            string str = param.Trim();
            if (str.Length >= 1)
            {
                var sub1 = str.Trim().Substring(0, 1);
                switch (sub1)
                {
                    case "m":
                        var cmdm = new VCommand { Cmd = "m" };
                        cmds.Add(cmdm);
                        sub1Read = true;
                        break;
                    case "l":
                        var cmdl = new VCommand { Cmd = "l" };
                        cmds.Add(cmdl);
                        sub1Read = true;
                        break;
                    case "c":
                        var cmdc = new VCommand { Cmd = "c" };
                        cmds.Add(cmdc);
                        sub1Read = true;
                        break;
                    case "x":
                        var cmdx = new VCommand { Cmd = "x" };
                        cmds.Add(cmdx);
                        sub1Read = true;
                        break;
                    case "e":
                        var cmde = new VCommand { Cmd = "e" };
                        cmds.Add(cmde);
                        sub1Read = true;
                        break;
                    case "t":
                        var cmdt = new VCommand { Cmd = "t" };
                        cmds.Add(cmdt);
                        sub1Read = true;
                        break;
                    case "r":
                        var cmdr = new VCommand { Cmd = "r" };
                        cmds.Add(cmdr);
                        sub1Read = true;
                        break;
                    case "v":
                        var cmdv = new VCommand { Cmd = "v" };
                        cmds.Add(cmdv);
                        sub1Read = true;
                        break;
                }
            }
            if(!sub1Read)
            {
                if (str.Length >= 2)
                {
                    var sub2 = str.Trim().Substring(0, 2);
                    switch (sub2)
                    {
                        case "nf":
                            var cmdnf = new VCommand { Cmd = "nf" };
                            cmds.Add(cmdnf);
                            sub2Read = true;
                            break;
                        case "ns":
                            var cmdns = new VCommand { Cmd = "ns" };
                            cmds.Add(cmdns);
                            sub2Read = true;
                            break;
                        case "ae":
                            var cmdae = new VCommand { Cmd = "ae" };
                            cmds.Add(cmdae);
                            sub2Read = true;
                            break;
                        case "al":
                            var cmdal = new VCommand { Cmd = "al" };
                            cmds.Add(cmdal);
                            sub2Read = true;
                            break;
                        case "at":
                            var cmdat = new VCommand { Cmd = "at" };
                            cmds.Add(cmdat);
                            sub2Read = true;
                            break;
                        case "ar":
                            var cmdar = new VCommand { Cmd = "ar" };
                            cmds.Add(cmdar);
                            sub2Read = true;
                            break;
                        case "wa":
                            var cmdwa = new VCommand { Cmd = "wa" };
                            cmds.Add(cmdwa);
                            sub2Read = true;
                            break;
                        case "wr":
                            var cmdwr = new VCommand { Cmd = "wr" };
                            cmds.Add(cmdwr);
                            sub2Read = true;
                            break;
                        case "qx":
                            var cmdqx = new VCommand { Cmd = "qx" };
                            cmds.Add(cmdqx);
                            sub2Read = true;
                            break;
                        case "qy":
                            var cmdqy = new VCommand { Cmd = "qy" };
                            cmds.Add(cmdqy);
                            sub2Read = true;
                            break;
                        case "qb":
                            var cmdqb = new VCommand { Cmd = "qb" };
                            cmds.Add(cmdqb);
                            sub2Read = true;
                            break;
                    }
                }
            }

            string remain;
            if(sub1Read)
            {
                remain = str.Trim().Substring(1);
                ReadVEle(remain, cmds, true);
            }else if(sub2Read)
            {
                remain = str.Trim().Substring(2);
                ReadVEle(remain,cmds, true);
            }else
            {
                remain = str.Trim();

                if (remain.Trim().Equals(""))
                {
                    if(!isSubString)
                    {
                        cmds[cmds.Count - 1].CmdParams.Add(0);
                    }
                }
                else
                {
                    int value;
                    if (int.TryParse(remain, out value))
                    {
                        if (cmds.Count > 0)
                        {
                            cmds[cmds.Count - 1].CmdParams.Add(value.ToString(CultureInfo.InvariantCulture));
                        }
                    }else
                    {
                        var tempstrs = new List<string>(new string[] {"m", "l", "c", "x", "e", "t", "r", "v",
                            "nf", "ns", "ae", "al", "at", "ar", "wa", "wr", "qx", "qy", "qb"});

                        bool stillcontain = false;
                        foreach (var t in tempstrs)
                        {
                            if (!remain.Contains(t)) continue;
                            stillcontain = true;
                            var splitstr = remain.Split(new[] { t }, StringSplitOptions.None);
                            if (cmds.Count < 1 || splitstr.Length <= 1) continue;
                            ReadVEle(splitstr[0], cmds, true);
                            var lastString = t + splitstr[1];
                            ReadVEle(lastString, cmds, true);
                            break;
                        }

                        if(!stillcontain)
                        {
                            if (remain.Trim().Contains("@"))
                            {
                                var delsub = new[] { '@' };
                                var splittedArray = remain.Split(delsub, StringSplitOptions.None);

                                if (cmds.Count > 0)
                                {
                                    if (!splittedArray[0].Trim().Equals(""))
                                    {
                                        int valueint2;
                                        if (int.TryParse(splittedArray[0], out valueint2))
                                        {
                                            cmds[cmds.Count - 1].CmdParams.Add(valueint2);
                                        }
                                        
                                    }
                                    for(int z = 1; z < splittedArray.Length; z++)
                                    {
                                        int valueint;
                                        if (!int.TryParse(splittedArray[z], out valueint)) continue;
                                        if (valueint < 128)
                                        {
                                            cmds[cmds.Count - 1].CmdParams.Add("@" + valueint);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            
        }
        
        public static string GetStringFromV(IEnumerable<VCommand> cmds)
        {
            var temp = "";
            foreach (var t1 in cmds)
            {
                temp += t1.Cmd + " ";
                temp = t1.CmdParams.Cast<object>().Aggregate(temp, (current, t) => current + (t + " "));
            }
            return temp.Trim();
        } 

        private static bool CheckFomulaEqn(string str)
        {
            if (String.IsNullOrEmpty(str))
            {
                return false;
            }
            var delimiters = new[] {' '};
            var temp = str.Trim().Split(delimiters, StringSplitOptions.None);

            if(temp.Length<4)
            {
                return false;
            }

            var vfc = new VFomulaCmd { Operation = temp[0].ToLower().Trim(), V = temp[1].ToLower().Trim(), P1 = temp[2].ToLower().Trim(), P2 = temp[3].ToLower().Trim() };

            if (!vfc.Operation.Equals("val") && !vfc.Operation.Equals("sum") && !vfc.Operation.Equals("product") &&
                !vfc.Operation.Equals("mid") && !vfc.Operation.Equals("abs") && !vfc.Operation.Equals("min") &&
                !vfc.Operation.Equals("max") && !vfc.Operation.Equals("if") && !vfc.Operation.Equals("mod") &&
                !vfc.Operation.Equals("atan2") && !vfc.Operation.Equals("sin") && !vfc.Operation.Equals("cos") &&
                !vfc.Operation.Equals("cosatan2") && !vfc.Operation.Equals("sinatan2") && !vfc.Operation.Equals("sqrt") &&
                !vfc.Operation.Equals("sumangle") && !vfc.Operation.Equals("ellipse") && !vfc.Operation.Equals("tan"))
            {
                return false;
            }

            if (!CheckAdjuctValueString(vfc.V) && !CheckFomulaString(vfc.V) && !vfc.V.Equals("width") &&
                !vfc.V.Equals("height") && !vfc.V.Equals("xcenter") && !vfc.V.Equals("ycenter") &&
                !vfc.V.Equals("xlimo") && !vfc.V.Equals("ylimo") && !vfc.V.Equals("hasstroke") &&
                !vfc.V.Equals("hasfill") && !vfc.V.Equals("pixellinewidth") && !vfc.V.Equals("pixelwidth") &&
                !vfc.V.Equals("pixelheight") && !vfc.V.Equals("emuwidth") && !vfc.V.Equals("emuheight") &&
                !vfc.V.Equals("emuwidth2") && !vfc.V.Equals("emuheight2"))
            {
                return false;
            }

            if (!CheckAdjuctValueString(vfc.P1) && !CheckFomulaString(vfc.P1) && !vfc.P1.Equals("width") &&
                !vfc.P1.Equals("height") && !vfc.P1.Equals("xcenter") && !vfc.P1.Equals("ycenter") &&
                !vfc.P1.Equals("xlimo") && !vfc.P1.Equals("ylimo") && !vfc.P1.Equals("hasstroke") &&
                !vfc.P1.Equals("hasfill") && !vfc.P1.Equals("pixellinewidth") && !vfc.P1.Equals("pixelwidth") &&
                !vfc.P1.Equals("pixelheight") && !vfc.P1.Equals("emuwidth") && !vfc.P1.Equals("emuheight") &&
                !vfc.P1.Equals("emuwidth2") && !vfc.P1.Equals("emuheight2"))
            {
                return false;
            }

            if (!CheckAdjuctValueString(vfc.P2) && !CheckFomulaString(vfc.P2) && !vfc.P2.Equals("width") &&
                !vfc.P2.Equals("height") && !vfc.P2.Equals("xcenter") && !vfc.P2.Equals("ycenter") &&
                !vfc.P2.Equals("xlimo") && !vfc.P2.Equals("ylimo") && !vfc.P2.Equals("hasstroke") &&
                !vfc.P2.Equals("hasfill") && !vfc.P2.Equals("pixellinewidth") && !vfc.P2.Equals("pixelwidth") &&
                !vfc.P2.Equals("pixelheight") && !vfc.P2.Equals("emuwidth") && !vfc.P2.Equals("emuheight") &&
                !vfc.P2.Equals("emuwidth2") && !vfc.P2.Equals("emuheight2"))
            {
                return false;
            }

            return true;
        }

        private static bool CheckFomulaString(string str)
        {
            if (str.Length > 1)
            {
                if (str[0].Equals('@'))
                {
                    var temp = str.Substring(1);
                    int value;
                    if(int.TryParse(temp, out value))
                    {
                        return value<128 && value >=0;
                    }
                    return false;
                }
                return false;
            }
            return false;
        }

        private static bool CheckAdjuctValueString(string str)
        {
            if (str.Length > 1)
            {
                if (str[0].Equals('#'))
                {
                    var temp = str.Substring(1);
                    int value;
                    if (int.TryParse(temp, out value))
                    {
                        return value < 8 && value >= 0;
                    }
                    return false;
                }
                return false;
            }
            return false;
        }
        
        public static VStyle ReadStyleFromString(string str)
        {
            var rs = new VStyle();

            if (String.IsNullOrEmpty(str))
            {
                return rs;
            }
            var delimiters = new[] {';', ':'};
            var temp = str.Trim().Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < temp.Length;i++ )
            {
                float fltemp = 0.0f;

                if(i<temp.Length-1)
                {
                    switch (temp[i].Trim().ToLower())
                    {
                        case "top":
                            fltemp = GetFloatFromString(temp[i + 1].Trim(), 0);
                            rs.Top = fltemp;
                            break;
                        case "margin-top":
                            fltemp = GetFloatFromString(temp[i + 1].Trim(), 0);
                            rs.Margintop = fltemp;
                            break;
                        case "center-y":
                            fltemp = GetFloatFromString(temp[i + 1].Trim(), 0);
                            rs.Centery = fltemp;
                            break;
                        case "left":
                            fltemp = GetFloatFromString(temp[i + 1].Trim(), 0);
                            rs.Left = fltemp;
                            break;
                        case "margin-left":
                            fltemp = GetFloatFromString(temp[i + 1].Trim(), 0);
                            rs.Marginleft = fltemp;
                            break;
                        case "center-x":
                            fltemp = GetFloatFromString(temp[i + 1].Trim(), 0);
                            rs.Centerx = fltemp;
                            break;
                        case "width":
                            fltemp = GetFloatFromString(temp[i + 1].Trim(), 100);
                            rs.Width = fltemp;
                            break;
                        case "height":
                            fltemp = GetFloatFromString(temp[i + 1].Trim(), 100);
                            rs.Height = fltemp;
                            break;
                    }
                }
            }
            return rs;
        }

        public static string GetStringFromStyle(VStyle style)
        {
            string temp = "";
            temp += "top:" + Convert.ToInt32(Math.Round(style.Top, 0, MidpointRounding.ToEven)) + ";";
            temp += "margin-top:" + Convert.ToInt32(Math.Round(style.Margintop, 0, MidpointRounding.ToEven)) + ";";
            temp += "center-y:" + Convert.ToInt32(Math.Round(style.Centery, 0, MidpointRounding.ToEven)) + ";";
            temp += "left:" + Convert.ToInt32(Math.Round(style.Left, 0, MidpointRounding.ToEven)) + ";";
            temp += "margin-left:" + Convert.ToInt32(Math.Round(style.Marginleft, 0, MidpointRounding.ToEven)) + ";";
            temp += "center-x:" + Convert.ToInt32(Math.Round(style.Centerx, 0, MidpointRounding.ToEven)) + ";";
            temp += "width:" + Convert.ToInt32(Math.Round(style.Width, 0, MidpointRounding.ToEven)) + ";";
            temp += "height:" + Convert.ToInt32(Math.Round(style.Height, 0, MidpointRounding.ToEven)) + ";";
            return temp;
        }
    }
}
